<script setup lang='ts' name="PhysicalReport">
import {onBeforeMount, onActivated, ref, reactive, CSSProperties, effect} from 'vue'
import {ElMessage, FormRules} from 'element-plus'
import {Dictionary, SeleteData} from '@/api/config'
import {Normal, NoNumber, getYearMonthDayStr, day, transfDicArrData, transfArrData} from '@/util/common'
import {OperButton, SearchFromItem} from '@/components/dTable/dHeader'
import {HeaderData} from '@/components/dTable/dTable'
import {PageConfig, defaultPage, defaultPageSize, defaultPageSizes, defaultLayout} from '@/components/dTable/dFooter'
import {getTeamListAll} from '@/api/publicHealthExamination/communitySettings'
import {GetReportList, SearchFromData, ReportListData, getReportList, PrintStatus, DistributionStatus, getSumDoctorList, getUserList} from '@/api/report/physicalReport'
import {sendReport, getReportData, getReportDoc, getPrintKeys} from '@/api/report/physicalReport'
import {loadCLodop, showCLodopTips, checkPrint, printPdf} from '@/util/cLodop'
import {getPdfBase64} from '@/util/pdf'
import {GenerateZip, downZip, preventDuplicate} from '@/util/zip'
import useCommon from '@/store/common'
import zhCN from 'ant-design-vue/es/locale/zh_CN'

import pageContainer from '@/components/pageContainer.vue'
import dTablePromote from '@/components/dTable/dTablePromote.vue'

//搜索表单验证
const searchFromRules = reactive<FormRules>({
  checkupNo:[
    {message:'长度应不超过20个字符', max:20, trigger: ['change', 'blur']},
    {message:'请输入汉字、字母、数字、字符', pattern:Normal, trigger: ['change', 'blur']}
  ],
  personName:[
    {message:'长度应不超过20个字符', max:20, trigger: ['change', 'blur']},
    {message:'请输入汉字、字母、字符', pattern:NoNumber, trigger: ['change', 'blur']}
  ]
})
//下拉数据
//日期类型
const dateTypeSeleteData = ref<Array<SeleteData>>([
  {label:'总检日期', value:'1'},
  {label:'体检日期', value:'2'},
  {label:'打印日期', value:'3'},
  {label:'发放日期', value:'4'}
])
//打印状态
const printSeleteData = ref<Array<SeleteData>>([
  {label:'未打印', value:PrintStatus.NOT},
  {label:'已打印', value:PrintStatus.HAS}
])
//发放状态
const distributionSeleteData = ref<Array<SeleteData>>([
  {label:'未发放', value:DistributionStatus.NOT},
  {label:'已发放', value:DistributionStatus.HAS}
])
//发放医生类型
const doctorTypeSeleteData = ref<Array<SeleteData>>([
  {label:'总检医生', value:'1'},
  {label:'打印医生', value:'2'},
  {label:'发放医生', value:'3'}
])
//性别
const genderSeleteData = ref<Array<SeleteData>>([])
//社区
const teamSeleteData = ref<Array<SeleteData>>([])
//医生
const doctorSeleteData = ref<Array<SeleteData>>([])

//获取基本搜索数据
const getBaseSearchData = ():GetReportList => {
  const time = Date.now()
  const startTime = getYearMonthDayStr(time - 7 * day)
  const endTime = getYearMonthDayStr(time)
  return {dateType:'2', doctorType:'2', time:[startTime, endTime], startTime, endTime}
}
//搜索数据
const searchFromData = reactive<GetReportList>(getBaseSearchData())
const doctorMap = reactive<Dictionary<Array<SeleteData>>>({})
//边界处理
const checkDoctor = () => {
  for (let i = 0, l = doctorSeleteData.value.length; i < l; i++) {
    if (doctorSeleteData.value[i].value === searchFromData.doctorId) {
      return
    }
  }
  searchFromData.doctorId = undefined
}

effect(() => {
  if (searchFromData.doctorType === '1') {
    if (!doctorMap['1']) {
      doctorMap['1'] = []
      getSumDoctorList().then((res) => {
        doctorMap['1'] = transfArrData(res.data.data, {userName:'label', id:'value'})
        doctorSeleteData.value = doctorMap['1']
        checkDoctor()
      })
    } else {
      doctorSeleteData.value = doctorMap['1']
      checkDoctor()
    }
  } else {
    if (!doctorMap['2']) {
      doctorMap['2'] = []
      getUserList().then((res) => {
        if (res.data.data) {
          doctorMap['2'] = transfArrData(res.data.data, {userName:'label', id:'value'})
          doctorSeleteData.value = doctorMap['2']
          checkDoctor()
        }
      })
    } else {
      doctorSeleteData.value = doctorMap['2']
      checkDoctor()
    }

  }
})

const common = useCommon.setup().store
const initSeleteData = () => {
  common.getDicData('gender').then((dicArr) => {
    genderSeleteData.value = transfDicArrData(dicArr)
  })
  getTeamListAll().then((res) => {
    if (res.data.data) {
      teamSeleteData.value = transfArrData(res.data.data, {name:'label', id:'value'})
    }
  })
}
//搜索项
const searchFromItems = ref<Array<SearchFromItem>>([])
effect(() => {
  searchFromItems.value = [
    {prop:'dateType', label:'', type:'slot', slotName:'dateType', class:{'report-type':true}},
    {prop:'checkupNo', label:'体检号', type:'input', placeholder:'请输入', enterSubmit:true},
    {prop:'personName', label:'姓名', type:'input', placeholder:'请输入', enterSubmit:true},
    {prop:'gender', label:'性别', type:'selete', seleteData:genderSeleteData.value, changeSubmit:false},
    {prop:'teamId', label:'社区', type:'selete', seleteData:teamSeleteData.value, changeSubmit:false},
    {prop:'printStatus', label:'打印状态', type:'selete', seleteData:printSeleteData.value, changeSubmit:false},
    {prop:'distributionStatus', label:'发放状态', type:'selete', seleteData:distributionSeleteData.value, changeSubmit:false},
    {prop:'doctorType', label:'', type:'slot', slotName:'doctorType', class:{'report-type':true}}
  ]
})


//操作按钮
const operButtons = ref<Array<OperButton>>([
  {label: '打印', type: 'noraml', iconConfig: {icon: 'common-print', type: 'custom', size:16}, code: 'report'},
  {label: '发放', type: 'noraml', iconConfig: {icon: 'Position', type: 'el', size:16}, code: 'grant'},
  {label: '下载', type: 'noraml', iconConfig: {icon: 'Download', type: 'el', size:16}, code: 'down'}
])

//分页配置
const pageConfig = reactive<PageConfig>({
  currentPage: defaultPage,
  pageSize: defaultPageSize,
  pageSizes: defaultPageSizes,
  total: 0,
  disabled: false,
  layout: defaultLayout
})

//显示加载
const showLoading = ref(false)
//表格数据
const tableData = ref<Array<ReportListData>>([])
//表格配置
const tableHeaderData = reactive<Array<HeaderData>>([
  {prop:'checkupNo', label:'体检号', columnType:'text', 'min-width':'125'},
  {prop:'personName', label:'姓名', columnType:'text', 'min-width':'130'},
  {prop:'idNo', label:'身份证号', columnType:'text', 'min-width':'200'},
  {prop:'gender', label:'性别', columnType:'text', 'min-width':'80'},
  {prop:'age', label:'年龄', columnType:'text', 'min-width':'80'},
  {prop:'phone', label:'联系电话', columnType:'text', 'min-width':'130'},
  {prop:'teamName', label:'社区', columnType:'text', 'min-width':'180'},
  {prop:'phyDate', label:'体检日期', columnType:'text', 'min-width':'130'},
  {prop:'inspectDate', label:'总检日期', columnType:'text', 'min-width':'130'},
  {prop:'printStatus', label:'打印状态', columnType:'slot', 'min-width':'115'},
  {prop:'printTime', label:'打印日期', columnType:'text', 'min-width':'130'},
  {prop:'distributionStatus', label:'发放状态', columnType:'slot', 'min-width':'115'},
  {prop:'distributionTime', label:'发放日期', columnType:'text', 'min-width':'130'}
])
//状态文字和样式
const getPrintStyle = (row:ReportListData) => {
  const style:CSSProperties = {}
  if (row.printStatus === PrintStatus.NOT) {
    style.color = 'var(--theme-color-warning)'
  }
  return style
}
const getDistributionStyle = (row:ReportListData) => {
  const style:CSSProperties = {}
  if (row.distributionStatus === DistributionStatus.NOT) {
    style.color = 'var(--theme-color-warning)'
  }
  return style
}
const getPrintName = (row:ReportListData) => {
  return row.printStatus === PrintStatus.NOT ? '未打印' : '已打印'
}
const getDistributionName = (row:ReportListData) => {
  return row.distributionStatus === DistributionStatus.NOT ? '未发放' : '已发放'
}


//组装参数
const getSearchParams = ():SearchFromData => {
  const {time, dateType, doctorType, doctorId, ...reset} = searchFromData
  reset.inspectDate = undefined
  reset.phyDate = undefined
  reset.printTime = undefined
  reset.distributionTime = undefined
  reset.startTime = undefined
  reset.endTime = undefined
  if (time) {
    const startTime = time[0] + ' 00:00:00'
    const endTime = time[1] + ' 23:59:59'
    reset.startTime = startTime
    reset.endTime = endTime
    if (dateType === '1') {
      reset.inspectDate = '1000-01-01 00:00:00'
    }
    else if (dateType === '2') {
      reset.phyDate = '1000-01-01 00:00:00'
    }
    else if (dateType === '3') {
      reset.printTime = '1000-01-01 00:00:00'
    }
    else if (dateType === '4') {
      reset.distributionTime = '1000-01-01 00:00:00'
    }
  }
  reset.inspectDoctorId = undefined
  reset.printDoctorId = undefined
  reset.distributionDoctorId = undefined
  if (doctorId) {
    if (doctorType === '1') {
      reset.inspectDoctorId = doctorId
    }
    else if (doctorType === '2') {
      reset.printDoctorId = doctorId
    }
    else if (doctorType === '3') {
      reset.distributionDoctorId = doctorId
    }
  }
  return reset
}
//搜索数据
const searchData = (resetPage?:boolean) => {
  if (resetPage)  pageConfig.currentPage = 1
  const page = pageConfig.currentPage
  const limit = pageConfig.pageSize
  const params = getSearchParams()
  showLoading.value = true
  getReportList({...params, page, limit}).then((res) => {
    showLoading.value = false
    tableData.value = res.data.data.records
    pageConfig.total = res.data.data.total ? res.data.data.total : 0
  }).catch((error) => {
    console.warn(error)
    showLoading.value = false
  })
}

//搜索事件
const onSubmit = () => {
  searchData(true)
}
//清空搜索表单事件
const onFormClear = () => {
  searchData(true)
}
//分页尺寸改变事件
const onSizeChange = () => {
  searchData(true)
}
//当前页改变事件
const onCurrentChange = () => {
  searchData()
}
//多选数据
const multipleData = ref<Array<ReportListData>>([])
//多选事件
const onMultipleSelection = (arr:Array<ReportListData>) => {
  multipleData.value = arr
}

//一般的打印字段
const printConfig = reactive<{keys:Array<string>, init:boolean}>({keys:[], init:false})
const initPrintKeys = () => {
  printConfig.init = false
  getPrintKeys().then((res) => {
    printConfig.keys = res.data.data ? res.data.data : []
    printConfig.keys.forEach((key) => {
      printConfig.keys.push(key + 'Name')
      printConfig.keys.push(key + 'Others')
    })
    printConfig.init = true
  }).catch(() => {
    printConfig.init = true
  })
}
//打印
const onReport = () => {
  //是否加载打印控件,选择打印机
  if (!showCLodopTips() || !checkPrint('report', true)) return
  const ids = multipleData.value.map((item) => item.id)
  showLoading.value = true
  getReportData(ids).then((res) => {
    const arr:Array<Promise<string>> = []
    res.data.data.forEach((item) => {
      const docArr = getReportDoc(item, true, printConfig.keys)
      docArr.forEach((doc) => {
        arr.push(getPdfBase64(doc, true))
      })
    })
    return Promise.all(arr)
  }).then((base64Arr) => {
    base64Arr.forEach((base64, i) => {
      printPdf('report', 'print', base64, i & 1 ? true : false)
    })
    showLoading.value = false
    searchData()
  }).catch((error) => {
    console.warn(error)
    showLoading.value = false
  })
}
//发放
const onGrant = () => {
  const ids = multipleData.value.map((item) => item.id)
  showLoading.value = true
  sendReport(ids).then(() => {
    ElMessage.success('操作成功')
    showLoading.value = false
    searchData()
  }).catch((error) => {
    console.warn(error)
    showLoading.value = false
  })
}
//下载
const onDown = () => {
  const ids = multipleData.value.map((item) => item.id)
  showLoading.value = true
  getReportData(ids).then((res) => {
    const arr:Array<Promise<string>> = []
    res.data.data.forEach((item) => {
      const docArr = getReportDoc(item, false, printConfig.keys)
      docArr.forEach((doc) => {
        arr.push(getPdfBase64(doc, true))
      })
    })
    return Promise.all(arr)
  }).then((base64Arr) => {
    const configs:Array<GenerateZip> = []
    base64Arr.forEach((base64, i) => {
      const name = multipleData.value[i] ? multipleData.value[i].personName : '检验报告'
      configs.push({data:base64, type:'base64', name})
    })
    preventDuplicate(configs, '.pdf')
    return downZip('检验报告.zip', configs)
  }).then(() => {
    showLoading.value = false
    searchData()
  }).catch((error) => {
    console.warn(error)
    showLoading.value = false
  })
}
//操作按钮
const onOperation = (name:string) => {
  if (!multipleData.value.length) {
    ElMessage.warning('请勾选数据')
    return
  }
  if (name === 'report') {
    if (!printConfig.init) {
      ElMessage.warning('正在获取打印字段...')
      return
    }
    onReport()
  }
  else if (name === 'grant') {
    onGrant()
  }
  else if (name === 'down') {
    if (!printConfig.init) {
      ElMessage.warning('正在获取打印字段...')
      return
    }
    onDown()
  }
}
onBeforeMount(() => {
  initSeleteData()
  loadCLodop()
})
onActivated(() => {
  searchData()
  initPrintKeys()
})

</script>

<template>
  <page-container>
    <d-table-promote
      search-from-justify="flexStart"
      show-selection
      :label-width="70"
      :show-loading="showLoading"
      :oper-buttons="operButtons"
      :page-config="pageConfig"
      :search-form-data="searchFromData"
      :search-form-items="searchFromItems"
      :search-rules="searchFromRules"
      :table-data="tableData"
      :table-header-data="tableHeaderData"
      @form-submit="onSubmit"
      @form-clear="onFormClear"
      @operation="onOperation"
      @multiple-selection="onMultipleSelection"
      @size-change="onSizeChange"
      @current-change="onCurrentChange"
    >
      <template #dateType>
        <div class="d-common-flex-row">
          <el-select
            v-model="searchFromData.dateType"
            placeholder="请选择"
            class="report-select-type"
          >
            <el-option v-for="item in dateTypeSeleteData" :key="''+item.value" :label="item.label" :value="item.value" />
          </el-select>
          <a-config-provider :locale="zhCN">
            <A-range-picker
              v-model:value="searchFromData.time"
              format="YYYY-MM-DD"
              value-format="YYYY-MM-DD"
              :allow-clear="false"
              :clearable="false"
              :show-time="false"
            />
          </a-config-provider>
        </div>
      </template>
      <template #doctorType>
        <div class="d-common-flex-row">
          <el-select
            v-model="searchFromData.doctorType"
            placeholder="请选择"
            class="report-select-type"
          >
            <el-option v-for="item in doctorTypeSeleteData" :key="''+item.value" :label="item.label" :value="item.value" />
          </el-select>
          <el-select
            v-model="searchFromData.doctorId"
            clearable
            placeholder="请选择"
            class="report-select"
          >
            <el-option v-for="item in doctorSeleteData" :key="''+item.value" :label="item.label" :value="item.value" />
          </el-select>
        </div>
      </template>
      <template #printStatus="scope">
        <span :style="getPrintStyle(scope.row)">{{ getPrintName(scope.row) }}</span>
      </template>
      <template #distributionStatus="scope">
        <span :style="getDistributionStyle(scope.row)">{{ getDistributionName(scope.row) }}</span>
      </template>
    </d-table-promote>
  </page-container>
</template>

<style>
.report-type .el-form-item__content{
  margin-left: 0 !important;
  width: unset;
}
.report-type .report-select-type{
  width: 106px;
  margin-right: 8px;
}
.report-type .ant-picker{
  width: 286px;
}
.report-type .report-select{
  width: 286px;
}
</style>